#!/bin/bash

# 这是一个由 Bash 实现的电台播放程序，它的图形界面采用 Gtkdialog 来编写。
# 本程序在 GPL v2 的条款下分发。
# 安装和使用详见 README.md 文档。
# 电台资源取自于网络，不保证长期有效。
# 脚本以及电台资源仅供个人学习之用，不可用于其他非法目的。
# (c) 2022 LanXing <lanxing0821@126.com>

### 当前工作目录 ###
export WORKDIR="$(dirname "$(readlink -f "$0")")"

### 导出环境
export XDG_DATA_DIRS="$WORKDIR/share:/usr/local/share:/usr/share:/usr/share/plasma:$XDG_DATA_DIRS"
export PATH="$WORKDIR/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:$PATH"
export GTK2_RC_FILES="$WORKDIR/gtk-2.0/.gtkrc-2.0:$WORKDIR/gtk-2.0/gtkrc"

### 检测是否已经安装 gtkdialog ###
if command -v gtkdialog > /dev/null ;then :
else
	zenity --title="错误信息" --error --width 240 --text="监测到你的系统并没有安装 gtkdialog ，脚本运行需要 gtkdialog ！"
	exit
fi

### 将脚本集成到系统 ###
if [ $EUID -ne 0 ]; then
	DESTINATION_DIR_DESKTOP="$HOME/.local/share/applications"
else
	DESTINATION_DIR_DESKTOP="/usr/share/applications"
fi

desktopFilePath="$DESTINATION_DIR_DESKTOP/GDRadio.desktop"

if [ -e "$desktopFilePath" ] ; then :
else
	for i in  $(install-dialog.gdl | grep -E '^[a-z_A-Z][a-zA-Z_0-9]*=".*"[[:blank:]]*$'); do
		eval $i
	done
	if [ "$EXIT" = "Yes" ]; then
		cat > "$desktopFilePath" <<-EOT
		#!/usr/bin/env xdg-open
		[Desktop Entry]
		Type=Application
		Version=1.0
		Name=GDRadio
		Name[zh_CN]=咯咚电台
		Exec="$WORKDIR/AppRun.fallback"
		Icon=GDRadio
		Comment=radio play script
		Comment[zh_CN]=电台播放脚本
		Categories=AudioVideo;Audio;Music;Player;
		StartupWMClass=GDRadio
		StartupNotify=false
		Terminal=false
		NoDisplay=false
		Hidden=false
		
		Actions=uninstall;
		
		[Desktop Action uninstall]
		Name=卸载 咯咚电台
		Exec="$WORKDIR/bin/uninstall.sh"
		EOT
		xdg-icon-resource install --novendor --size 512 "$WORKDIR/GDRadio.png"
		xdg-desktop-menu forceupdate
	fi
fi

### 台标封面目录 ###
export COVER_DIR="$WORKDIR/cover"
[ -d "$COVER_DIR" ] || mkdir "$COVER_DIR"
if [ ! -h "$WORKDIR/share/pixmaps" ]; then
    ln -sf "$COVER_DIR" "$WORKDIR/share/pixmaps"
fi

### 程序所需的数据 ###
export DATADIR="$WORKDIR/data"
export RADIODATA="$DATADIR/radioData.json"
export DATAFRAMES="$DATADIR/FramesData.fallback"
[ -d "$DATADIR" ] || mkdir "$DATADIR"
if [ ! -h "$RADIODATA" ];then
	ln -sf "$WORKDIR/radioData.json" "$RADIODATA"
fi

funcDataFramesCreate() {
I=$IFS
IFS=$'\n'
local CategoryName_map=$(jq -r .[].categoryName "$RADIODATA")
local array_map=($CategoryName_map)
for ((i=0;i<${#array_map[@]};i++)); do
	local RadioList=$(jq -r .[$i].RadioList[].name "$RADIODATA")
	local Category_Name=$(jq -r .[$i].categoryName "$RADIODATA")
	local array=($RadioList)
	for ((j=0;j<${#array[@]};j++)); do
		local Radio_Name=${array[j]}
		local Cover_Url=$(jq -r .[$i].RadioList[$j].coverSmall "$RADIODATA" | awk 'BEGIN{FS="!"}{print $1}')
		local Radio_Cover=$(echo ${Cover_Url##*/} | cut -d\. -f1)
		local Cover_Pic="$COVER_DIR/${Radio_Cover}.png"
		[ -f "$Cover_Pic" ] || curl "$Cover_Url"  -o "$Cover_Pic" >&/dev/null
		echo "$((j+1))|$Radio_Name|$Category_Name|$i $j"
	done
done
IFS=$I
}
# 生成表格数据
[ -f "$DATAFRAMES" ] || funcDataFramesCreate > "$DATAFRAMES"

### 以决定是否要使用系统标题栏和边框，默认为 false ###
export DECORATED_STATE="$DATADIR/decorated.state"
[ -f "$DECORATED_STATE" ] || echo -n false > "$DECORATED_STATE"

set_decorated_start(){
shopt -s nocasematch
if [[ "$1" = false ]];then
	echo '<window name="windowN" resizable="true" decorated="false" title="GDRadio" icon-name="GDRadio" border-width="0" height-request="360" width-request="720" window-position="1">
	<notebook name="bcr" show-tabs="false">
		<vbox border-width="2" spacing="0">
		
			<!-- 标题栏 -->
			<hbox border-width="0" spacing="0">
			
				<!-- 窗口图标以及最小化按钮 -->
				<button name="minimizeButton" height-request="24" width-request="24" tooltip-text="最小化" can-focus="false">
					<label>""</label>
					<action signal="button-press-event">xdotool getactivewindow windowminimize</action>
				</button>
				
				<!-- 窗口标题以及拖动区域 -->
				<menubar name="winBar" space-expand="false" space-fill="false" width-request="660">
					<menu visible="false"><menuitem stock-id="gtk-quit"></menuitem><label>""</label></menu>
				</menubar>
				
				<!-- 窗口关闭按钮 -->
				<button name="closeButton" height-request="24" width-request="24" tooltip-text="关闭" can-focus="false">
					<label>""</label>
					<action signal="button-release-event" type="exit">quit_now</action>
				</button>
				
			</hbox>
			
			<text height-request="5" label=" "></text>'
else
	echo '<window resizable="false" allow-grow="false" title="咯咚电台" icon-name="GDRadio" border-width="0" height-request="330" width-request="720" window-position="1">
	<eventbox name="BgTreeColor" above-child="false" visible-window="true">
		<vbox>'
fi
shopt -u nocasematch
}
set_decorated_end(){
shopt -s nocasematch
if [[ "$1" = false ]];then
	echo '</notebook>'
else
	echo '</eventbox>'
fi
shopt -u nocasematch
}

### 数据缓存目录，关机后会自动清空。 ###
export CACHEDIR="/dev/shm/GDRadio"
[ -d "$CACHEDIR" ] || mkdir "$CACHEDIR"

export EXPORTVALUE1="$CACHEDIR/ExportValue1.device"
export EXPORTVALUE2="$CACHEDIR/ExportValue2.device"
export CATEGORYINDEX="$CACHEDIR/CategoryIndex.device"
export PLAYERPID="$CACHEDIR/PlayerPid.device"
export PLAYSTATE="$CACHEDIR/PlayState.device"
export PLAYERSTATE="$CACHEDIR/PlayerState.svg"
export COVERSMALL="$CACHEDIR/CoverSmall.png"
export RADIONAME="$CACHEDIR/RadioName.device"
export CATEGORYNAME="$CACHEDIR/CategoryName.device"
export SCROLLINFO="$CACHEDIR/scrollinfo.device"
export RESTART_SCRIPT="$CACHEDIR/RestartScript.device"
export PLAYPIXMAPS="$WORKDIR/share/icons/hicolor/16x16/actions/player-play.svg"
export PAUSEPIXMAPS="$WORKDIR/share/icons/hicolor/16x16/actions/player-pause.svg"

[ -f "$EXPORTVALUE1" ] || echo -n 0 > "$EXPORTVALUE1"
[ -f "$EXPORTVALUE2" ] || echo -n 0 > "$EXPORTVALUE2"
[ -f "$CATEGORYINDEX" ] || echo -n 0 > "$CATEGORYINDEX"
[ -f "$PLAYERPID" ] || : > "$PLAYERPID"
[ -f "$PLAYSTATE" ] || echo -n 1 > "$PLAYSTATE"
if [ $(<"$PLAYSTATE") = 1 ];then
	ln -sf "$PAUSEPIXMAPS" "$PLAYERSTATE"
else
	ln -sf "$PLAYPIXMAPS" "$PLAYERSTATE"
fi
[ -f "$COVERSMALL" ] || getcover.sh
[ -f "$RADIONAME" ] || getradioname.sh
[ -f "$CATEGORYNAME" ] || getcategoryname.sh
[ -f "$SCROLLINFO" ] || scrollinfo.sh
echo -n no > "$RESTART_SCRIPT"

### 与 MPV 音量控制相关的文件 ###
export MPV_SOCKET="$CACHEDIR/mpv-socket.device"
export MPV_VOLUME="$CACHEDIR/mpv-volume.device"
[ -S "$MPV_SOCKET" ] || : > "$MPV_SOCKET"
[ -f "$MPV_VOLUME" ] || echo -n 100% > "$MPV_VOLUME"

### 将帮助对话框存入环境变量，启动会更快 ###
export HELPWINDOW='
<window title="快捷键操作" window-position="3" allow-grow="false" icon-name="GDRadio" skip-taskbar-hint="true" decorated="false" border-width="0">
	<eventbox name="BgColor" above-child="false" visible-window="true">
	<vbox>
		<hbox space-expand="true" space-fill="true" width-request="500">
			<pixmap>
				<input file icon="GDRadio"></input>
				<height>128</height>
			</pixmap>
			<text xalign="0" justify="0" wrap="true" name="TextBoldColors">
				<label>"
				
	← 		播放上一个频道
	→ 		播放下一个频道
	p 		播放/停止
	v 		音量调节
	< 		转到上一组电台
	> 		转到下一组电台
	t		打开切换窗口装饰对话框
	h 		打开本对话框
	q 		退出
				"</label>
			</text>
		</hbox>
		<text xalign="0" justify="0" wrap="false" name="TextColors">
			<label>此对话框失去聚焦后会自动退出；你也可以按 Q 键或 Esc 键退出！</label>
		</text>
	</vbox>
	</eventbox>
	<variable>HELPWINDOW</variable>
	<action signal="focus-out-event">closewindow:HELPWINDOW</action>
	<action signal="key-press-event" condition="command_is_true( [ $KEY_RAW = 0x18 ] && echo true )">closewindow:HELPWINDOW</action>
	<action signal="key-press-event" condition="command_is_true( [ $KEY_RAW = 0x9 ] && echo true )">closewindow:HELPWINDOW</action>
</window>
'

### 将音量调节对话框存入环境变量，启动会更快 ###
export VOLUMEADJUST='
<window startup-id="volume-adjust" name="BgColor" opacity="0.7" skip-taskbar-hint="true" skip-pager-hint="true" default-height="200" default-width="30" decorated="false">
	<vscale space-expand="true" range-min="0" range-max="150" range-step="1" value-pos="3" digits="0" inverted="true" can-focus="true">
		<variable>VSVOL</variable>
		<input>cat "$MPV_VOLUME"</input>
		<action>echo "set volume $VSVOL" | socat - "$MPV_SOCKET"</action>
		<action>echo -n ${VSVOL}% > "$MPV_VOLUME"</action>
	</vscale>
	<variable>VOLUMEADJUST</variable>
	<action signal="map-event">xdotool getactivewindow windowmove $(xdotool getmouselocation | sed "s/[xy]:\|scree.*//g")</action>
	<action signal="focus-out-event">closewindow:VOLUMEADJUST</action>
	<action signal="key-press-event" condition="command_is_true( [ $KEY_RAW = 0x18 ] && echo true )">closewindow:VOLUMEADJUST</action>
	<action signal="key-press-event" condition="command_is_true( [ $KEY_RAW = 0x9 ] && echo true )">closewindow:VOLUMEADJUST</action>
</window>
'

### 切换窗口装饰 ###
export TOGGLE_DECORATED='
<window resizable="false" allow-grow="false" title="切换窗口装饰" icon-name="GDRadio" window-position="3">
	<eventbox name="BgTreeColor" above-child="false" visible-window="true">
		<vbox>
			<frame 定制 电台窗口>
				<checkbox height-request="48" can-focus="false">
					<label>使用系统标题栏和边框；当窗口无法拖动时，建议勾选。</label>
					<input>cat "$DECORATED_STATE"</input>
					<variable>DECORATED</variable>
				</checkbox>
			</frame>
			<hbox>
				<button>
					<label>"  取消"</label>
					<input file icon="slash"></input>
					<action>closewindow:TOGGLE_DECORATED</action>
				</button>
				<button>
					<label>"  确定"</label>
					<input file icon="check-circle"></input>
					<action>echo -n $DECORATED > "$DECORATED_STATE"</action>
					<action>echo -n yes > "$RESTART_SCRIPT"</action>
					<action>exit:OK</action>
				</button>
			</hbox>
		</vbox>
	</eventbox>
	<variable>TOGGLE_DECORATED</variable>
</window>
'

### 分类菜单 ###
# 模板
template(){
echo '						<eventbox name="BgTreeColor" above-child="true" visible-window="true">
							<text name="TextBoldColors" xalign="0" space-expand="true" space-fill="true" width-request="70">
								<label>'"$2"'</label>
							</text>
							<variable>Menuitem'"$1"'</variable>
							<action signal="enter-notify-event">hide:Menuitem'"$1"'</action>
							<action signal="enter-notify-event">show:Menuitem'"$1"'B</action>
						</eventbox>
						<eventbox name="BgColor" above-child="true" visible-window="true" visible="false">
							<text name="TextBoldColors" xalign="0" space-expand="true" space-fill="true" width-request="70">
								<label>'"$2"'</label>
							</text>
							<variable>Menuitem'"$1"'B</variable>
							<action signal="leave-notify-event">show:Menuitem'"$1"'</action>
							<action signal="leave-notify-event">hide:Menuitem'"$1"'B</action>
							<action signal="button-release-event">echo -n '"$1"' > "$CATEGORYINDEX"</action>
							<action signal="button-release-event">echo -n '"$2"' > "$CATEGORYNAME"</action>
							<action signal="button-release-event">closewindow:CATEGORY_MENU</action>
						</eventbox>'
}
# 创建菜单项
MenuitemCreate(){
I=$IFS
IFS=$'\n'
local CategoryName_map=$(jq -r .[].categoryName "$RADIODATA")
local array_map=($CategoryName_map)
echo '<hbox spacing="0" border-width="3">'
for ((i=0;i<${#array_map[@]};i++)); do
	if ((i > 0 ? i%5 == 0 : 0));then
	echo '					</hbox>
					<hbox spacing="0" border-width="3">'
	fi
	template $i $(jq -r .[$i].categoryName "$RADIODATA")
done
echo '					</hbox>'
IFS=$I
}
# 生成源码
[ -f "$DATADIR/category_menu.src" ] || cat >> "$DATADIR/category_menu.src" <<EOF
# shellcheck shell=bash disable=SC2239
# file name：category_menu.src
export CATEGORY_MENU='
<window startup-id="category-menu" decorated="false" border-width="0" skip-taskbar-hint="true" resizable="false" modal="true" space-expand="true" space-fill="true">
	<eventbox name="CategoryMenu" above-child="false">
		<vbox border-width="1">
			<eventbox name="BgTreeColor">
				<vbox spacing="0" border-width="7">
					$(MenuitemCreate)
				</vbox>
			</eventbox>
		</vbox>
	</eventbox>
	<variable>CATEGORY_MENU</variable>
	<action signal="map-event">xdotool getactivewindow windowmove \$(xdotool getmouselocation | sed "s/[xy]:\|scree.*//g")</action>
	<action signal="focus-out-event">closewindow:CATEGORY_MENU</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x18 ] && echo true )">closewindow:CATEGORY_MENU</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x9 ] && echo true )">closewindow:CATEGORY_MENU</action>
</window>
'
EOF
# 读取源码
. "$DATADIR/category_menu.src"

### 阻止程序多开 ###
mwpid=$(ps -ef | grep "gtkdialog --class=GDRadio --name=GDRadio --stdin" | grep -v grep | awk '{printf $2}')
if [ "$mwpid" ];then
	command -v wmctrl > /dev/null && wmctrl -a "GDRadio" -x
	#xdotool search --name GDRadio windowactivate
    exit
fi

### 启动主程序窗口 ###
cat <<EOF | sed '/<!--.*-->/d' | gtkdialog --class=GDRadio --name=GDRadio --stdin
$(set_decorated_start $(cat "$DECORATED_STATE") )
			
			<!-- 播放区域 -->
			<hbox border-width="5">
				<vbox width-request="300">
					<text label=" "></text>
					
					<!-- 显示台标封面 -->
					<pixmap>
						<input file>$COVERSMALL</input>
						<height>160</height>
						<variable>cover</variable>
					</pixmap>
					
					<!-- 显示频道名称 -->
					<text xalign="0.5" name="TextBoldColors">
						<input file>$RADIONAME</input>
						<variable>radioname</variable>
					</text>
					
					<!-- 控制按钮 -->
					<hbox space-expand="true">
						<text label=" " width-request="48"></text>
						<button width-request="32" relief="2" can-focus="false" focus-on-click="false" tooltip-text="播放上一个">
							<input file icon="go-previous-channel"></input>
							<action>playprevious.sh</action>
							<action>ln -sf "\$PAUSEPIXMAPS" "\$PLAYERSTATE"</action>
							<action>refresh:cover</action>
							<action>refresh:radioname</action>
							<action>refresh:playerstate</action>
							<action>refresh:scrollinfo</action>
						</button>
						<button width-request="32" relief="2" can-focus="false" focus-on-click="false" tooltip-text="播放/停止">
							<input file>$PLAYERSTATE</input>
							<variable>playerstate</variable>
							<action>playerstate.sh</action>
							<action condition="file_is_true($PLAYSTATE)">ln -sf "\$PLAYPIXMAPS" "\$PLAYERSTATE"</action>
							<action condition="file_is_false($PLAYSTATE)">ln -sf "\$PAUSEPIXMAPS" "\$PLAYERSTATE"</action>
							<action>refresh:playerstate</action>
						</button>
						<button width-request="32" relief="2" can-focus="false" focus-on-click="false" tooltip-text="播放下一个">
							<input file icon="go-next-channel"></input>
							<action>playnext.sh</action>
							<action>ln -sf "\$PAUSEPIXMAPS" "\$PLAYERSTATE"</action>
							<action>refresh:cover</action>
							<action>refresh:radioname</action>
							<action>refresh:playerstate</action>
							<action>refresh:scrollinfo</action>
						</button>
						<button width-request="32" relief="2" can-focus="false" focus-on-click="false" tooltip-text="音量调节">
							<input file icon="volume-control"></input>
							<action>launch:VOLUMEADJUST</action>
						</button>
						<button width-request="32" relief="2" can-focus="false" focus-on-click="false" tooltip-text="全部分类">
							<input file icon="category-indicator"></input>
							<action>launch:CATEGORY_MENU</action>
						</button>
						<text label=" " width-request="48"></text>
					</hbox>
					
				</vbox>
				
				<!-- 频道选择区域 -->
				<frame>
				<vbox width-request="400">
				
					<!-- 控制按钮 -->
					<eventbox name="BgTreeColor" above-child="false" visible-window="true">
					<hbox space-expand="true">
						<button width-request="160" relief="2" can-focus="false" focus-on-click="false" tooltip-text="转到上一组电台">
							<input file icon="go-previous-group"></input>
							<action>goprevious.sh</action>
							<action>refresh:categoryname</action>
							<action>refresh:index</action>
						</button>
						<text xalign="0.5" name="TextBoldColors" file-monitor="true">
							<input file>$CATEGORYNAME</input>
							<variable>categoryname</variable>
							<action signal="file-changed">refresh:categoryname</action>
							<action signal="file-changed">refresh:index</action>
						</text>
						<button width-request="160" relief="2" can-focus="false" focus-on-click="false" tooltip-text="转到下一组电台">
							<input file icon="go-next-group"></input>
							<action>gonext.sh</action>
							<action>refresh:categoryname</action>
							<action>refresh:index</action>
						</button>
					</hbox>
					</eventbox>
					
					<!-- 电台频道列表 -->
					<notebook show-tabs="false" space-fill="true" space-expand="true">
						<tree column-visible="true|true|false|false" space-fill="true" space-expand="true" hover-selection="true" headers-clickable="false" headers-visible="true" enable-search="false" exported-column="3">
							<label>"编号|频道|分组|导出值"</label>
							<height>210</height>
							<width>360</width>
							<input>cat "\$DATAFRAMES" | grep "|\$categoryname|" </input>
							<variable>index</variable>
							
							<!-- 鼠标（左中右键）单击播放 -->
							<action signal="button-release-event">dclickaction.sh \$index</action>
							<action signal="button-release-event">ln -sf "\$PAUSEPIXMAPS" "\$PLAYERSTATE"</action>
							<action signal="button-release-event">refresh:cover</action>
							<action signal="button-release-event">refresh:radioname</action>
							<action signal="button-release-event">refresh:playerstate</action>
							<action signal="button-release-event">refresh:scrollinfo</action>
							
							<!-- 选定条目后，按回车键或空格键播放 -->
							<action signal="key-release-event" condition="command_is_true([ \$KEY_RAW = 0x24 -o \$KEY_RAW = 0x41 ] && echo true)">dclickaction.sh \$index</action>
							<action signal="key-release-event" condition="command_is_true([ \$KEY_RAW = 0x24 -o \$KEY_RAW = 0x41 ] && echo true)">ln -sf "\$PAUSEPIXMAPS" "\$PLAYERSTATE"</action>
							<action signal="key-release-event" condition="command_is_true([ \$KEY_RAW = 0x24 -o \$KEY_RAW = 0x41 ] && echo true)">refresh:cover</action>
							<action signal="key-release-event" condition="command_is_true([ \$KEY_RAW = 0x24 -o \$KEY_RAW = 0x41 ] && echo true)">refresh:radioname</action>
							<action signal="key-release-event" condition="command_is_true([ \$KEY_RAW = 0x24 -o \$KEY_RAW = 0x41 ] && echo true)">refresh:playerstate</action>
							<action signal="key-release-event" condition="command_is_true([ \$KEY_RAW = 0x24 -o \$KEY_RAW = 0x41 ] && echo true)">refresh:scrollinfo</action>
						</tree>
					</notebook>
					
				</vbox>
				</frame>
			</hbox>
			
			<!-- 显示底部信息 -->
			<eventbox border-width="5" name="BgScrollPixmap" above-child="false" visible-window="true">
			<hbox space-expand="true" space-fill="true" height-request="20">
				<text name="TextColors" xalign="0.03">
					<variable>scrollinfo</variable>
					<input file>$SCROLLINFO</input>
				</text>
				<text name="TextColors" xalign="1">
					<variable>clock</variable>
					<input>date +%H:%M:%S</input>
				</text>
			</hbox>
			</eventbox>
			
			<!-- 计时器 -->
			<timer milliseconds="true" interval="200" visible="false">
				<action>echo -n "\$(expr substr "\$scrollinfo" 2 \${#scrollinfo})\$(expr substr "\$scrollinfo" 1 1)" > "\$SCROLLINFO"</action>
				<action type="refresh">scrollinfo</action>
				<action type="refresh">clock</action>
			</timer>
			
		</vbox>
	$(set_decorated_end $(cat "$DECORATED_STATE") )
	
	<!-- 开始播放 -->
	<action signal="show">refresh:index</action>
	<action signal="show">playerstate.sh</action>
	
	<!-- 快捷键设置 -->
	<!-- 转到上一组电台 -->
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x3b ] && echo true )">goprevious.sh</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x3b ] && echo true )">refresh:categoryname</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x3b ] && echo true )">refresh:index</action>
	
	<!-- 转到下一组电台 -->
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x3c ] && echo true )">gonext.sh</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x3c ] && echo true )">refresh:categoryname</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x3c ] && echo true )">refresh:index</action>
	
	<!-- 播放上一个频道 -->
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x71 ] && echo true )">playprevious.sh</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x71 ] && echo true )">ln -sf "\$PAUSEPIXMAPS" "\$PLAYERSTATE"</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x71 ] && echo true )">refresh:cover</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x71 ] && echo true )">refresh:radioname</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x71 ] && echo true )">refresh:playerstate</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x71 ] && echo true )">refresh:scrollinfo</action>
	
	<!-- 播放下一个频道 -->
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x72 ] && echo true )">playnext.sh</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x72 ] && echo true )">ln -sf "\$PAUSEPIXMAPS" "\$PLAYERSTATE"</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x72 ] && echo true )">refresh:cover</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x72 ] && echo true )">refresh:radioname</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x72 ] && echo true )">refresh:playerstate</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x72 ] && echo true )">refresh:scrollinfo</action>
	
	<!-- 播放/停止 -->
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x21 ] && echo true )">playerstate.sh</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x21 ] && echo true )">[ \$(cat \$PLAYSTATE) = 1 ] && ln -sf "\$PLAYPIXMAPS" "\$PLAYERSTATE"</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x21 ] && echo true )">[ \$(cat \$PLAYSTATE) = 0 ] && ln -sf "\$PAUSEPIXMAPS" "\$PLAYERSTATE"</action>
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x21 ] && echo true )">refresh:playerstate</action>
	
	<!-- 音量调节 -->
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x37 ] && echo true )">launch:VOLUMEADJUST</action>
	
	<!-- 打开切换窗口装饰对话框 -->
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x1c ] && echo true )">launch:TOGGLE_DECORATED</action>
	
	<!-- 打开帮助对话框 -->
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x2b ] && echo true )">launch:HELPWINDOW</action>
	
	<!-- 退出程序 -->
	<action signal="key-press-event" condition="command_is_true( [ \$KEY_RAW = 0x18 ] && echo true )">exit:Close</action>
</window>
EOF

### 退出程序 ###
echo -n 0 > "$PLAYSTATE"
playerstate.sh
echo -n 1 > "$PLAYSTATE"
: > "$PLAYERPID"
cat "$EXPORTVALUE1" > "$CATEGORYINDEX"
getcategoryname.sh

if [ "$(cat "$RESTART_SCRIPT")" = yes ];then
	"$(readlink -f "$0")"
else
	exit
fi
